package n.d.l.svn.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import n.d.l.svn.bean.Patch;
import n.d.l.svn.bean.PatchLog;
import n.d.l.svn.bean.Project;
import n.d.l.svn.bean.ResponseBean;
import n.d.l.svn.bean.SvnCommand;
import n.d.l.svn.bean.SvnLog;
import n.d.l.svn.bean.SysCommandResponse;
import n.d.l.svn.mapper.log.PatchLogMapper;
import n.d.l.svn.mapper.project.ProjectMapper;
import n.d.l.utils.Utils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
public class PatchService {

	private static Logger log = LoggerFactory.getLogger(PatchService.class);
	@Autowired
	private ProjectMapper projectMapper;
	@Autowired
	private PatchLogMapper patchLogMapper;
	@Value("${patch.log.path}")
	private String patchLogPatch;
	
	public List<SvnLog> findSvnLogs(Project project) throws IOException, ParseException {
		// 更新本地到最新
		List<String> lines = Utils.doCommand(SvnCommand.UPDATE, new File(project.getSvnDir()));

		PatchLog plog= patchLogMapper.getTopLog(project.getId());
		String preVersion = "";
		if(plog != null){
			preVersion = plog.getVersionEnd();
		}
		
		SysCommandResponse commandResp = Utils.getCommandResponse(SvnCommand.LOGLIST, new File(project.getSvnDir()));
		BufferedReader reader = commandResp.getReader();
		String line;
		List<SvnLog> svnLogs = new ArrayList<SvnLog>();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
		while ((line = reader.readLine()) != null) {
			if (line.startsWith("r") && line.endsWith("line")) {
				SvnLog svnLog = new SvnLog();
				String[] arr = line.split("\\|");
				svnLog.setVersion(arr[0].trim());
				svnLog.setCommitUser(arr[1].trim());
				String timeString = arr[2].trim();
				timeString = timeString.substring(0, timeString.indexOf("("));
				svnLog.setCommitTime(format.parse(timeString));
				svnLogs.add(svnLog);
				if(svnLog.getVersion().equals(preVersion)){
					break;
				}
			}
		}
		commandResp.resoucesClose();
		return svnLogs;
	}
	
	public Patch diff(String versionStart, String versionEnd, Project project) throws IOException, ParseException {
		String command = String.format("%s -v -r %s:%s", SvnCommand.LOGLIST, versionStart, versionEnd);
		SysCommandResponse commandResp = Utils.getCommandResponse(command, new File(project.getSvnDir()));
		BufferedReader reader = commandResp.getReader();
		Patch path = new Patch();
		path.setRelativeUrl(project.getRelativeUrl());
		String line;
		while((line=reader.readLine()) != null){
			if(line.startsWith(" ")){
				path.addRecord(line);
			}
		}
		commandResp.resoucesClose();
		
		return path;
	}
	
	@Transactional(readOnly = false)
	public ResponseBean doPatch(String patchFile, String ignoreFile, String removeFile, Project project, String versionStart, String versionEnd) throws IOException{
		ResponseBean resp = new ResponseBean();
		//创建补丁目录文件
		File pathFile = new File(project.getPatchDir() + File.separator + project.getName());
		if(pathFile.exists()){
			FileUtils.deleteDirectory(pathFile);
		}
		pathFile.mkdirs();
		//复制补丁
		for(String fn : patchFile.split(",")){
			String sFile = project.getLocalDir() + File.separatorChar + fn;
			File srcFile = new File(sFile);
			if(!srcFile.exists()){
				resp.setSuccess(false);
				resp.setMsg(String.format("文件[%s]不存在", fn));
				return resp;
			}
			if(srcFile.isDirectory()){
				continue;
			}
			String dFile = pathFile.getAbsolutePath() + File.separatorChar + fn;
			FileUtils.copyFile(srcFile, new File(dFile));
		}
		//忽略文件更新
		project.setIgnores(ignoreFile);
		project.setLastUpdateTime(new Date());
		projectMapper.updateIgnore(project);
		//记录日志
		PatchLog plog = new PatchLog();
		plog.setCreateTime(new Date());
		plog.setLogPath(String.valueOf(plog.getCreateTime().getTime()));
		plog.setVersionStart(versionStart);
		plog.setVersionEnd(versionEnd);
		plog.setProject(project);
		patchLogMapper.save(plog);
		log.info("日志记录成功");
		//保存日志
		File logFile = new File(patchLogPatch + plog.getLogPath() + ".log");
		logFile.createNewFile();
		List<String> lines = new ArrayList<>();
		lines.add("补丁文件");
		lines.addAll(Arrays.asList(patchFile.split(",")));
		if(StringUtils.isNotEmpty(ignoreFile)){
			lines.add("忽略文件");
			lines.addAll(Arrays.asList(ignoreFile.split(",")));
		}
		if(StringUtils.isNotEmpty(removeFile)){
			lines.add("需删除文件");
			lines.addAll(Arrays.asList(removeFile.split(",")));
		}
		FileUtils.writeLines(logFile, lines);
		log.info("本地日志文件保存成功：" + logFile.getAbsolutePath());
		return resp;
	}
}
